package pers.cz.quartz.core;

import pers.cz.mapper.SystemJobLogMapper;
import pers.cz.mapper.SystemJobMapper;
import pers.cz.model.SystemJob;
import pers.cz.spring.SpringContextUtil;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 核心工厂类
 * @program: PostGirl-panent
 * @description: QuartzJobFactory
 * @author: Cheng Zhi
 * @create: 2021-05-09 17:48
 **/
public class QuartzJobFactory_new {

    private static Logger logger = LoggerFactory.getLogger(QuartzJobFactory_new.class);

    private static Scheduler scheduler = null;
    private static final String CONFIG_NAME = "quartz.properties";
    private static final String GROUP_NAME = Scheduler.DEFAULT_GROUP;

    public void initJobs() throws SchedulerException, ClassNotFoundException {

        SystemJobMapper systemJobMapper = SpringContextUtil.getBean(SystemJobMapper.class);
        SystemJobLogMapper systemJobLogMapper = SpringContextUtil.getBean(SystemJobLogMapper.class);

        List<SystemJob> systemJobList = systemJobMapper.selectAllSystemJobs();

        int count = 0;
        int success = 0;
        int error = 0;

        if (systemJobList != null && systemJobList.size() > 0) {

            SchedulerFactory factory = new StdSchedulerFactory();
            Scheduler scheduler = factory.getScheduler();

            for (SystemJob systemJob : systemJobList) {

                String jobName = systemJob.getJobName();
                String tiggerName = systemJob.getTriggerName();
                String state = getTriggerState(tiggerName);

                if ("NONE".equals(state)) {

                }
                addJob(systemJob);
                count ++;
            }
        }


    }

    /**
     * 获取触发器状态
     * NONE: 不存在
     * NORMAL: 正常
     * PAUSED: 暂停
     * COMPLETE:完成
     * ERROR : 错误
     * BLOCKED : 阻塞
     * @param tiggerName
     * @return
     */
    public static String getTriggerState(String tiggerName){
        TriggerKey triggerKey = TriggerKey.triggerKey(tiggerName, GROUP_NAME);
        String name = null;
        try {

            Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
            name = triggerState.name();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return name;
    }


    /**
     * @Description: 立即运行任务，这里的立即运行，只会运行一次，方便测试时用。
     * @param jobName
     */
    public static void triggerJob(String jobName) throws SchedulerException {
        if (scheduler == null) {
            StdSchedulerFactory factory = new StdSchedulerFactory(CONFIG_NAME);
            scheduler = factory.getScheduler();
        }
        JobKey jobKey = JobKey.jobKey(jobName, GROUP_NAME);
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 立即运行任务，这里的立即运行，只会运行一次，方便测试时用。
     * @param jobName
     * @param jobGroupName
     * @date 2018年5月17日 上午10:03:26
     */
    public static void triggerJob(String jobName, String jobGroupName) {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }


    /**
     * @Description:获取最近8次执行时间
     * @param cron
     */
    public static List<String> getRecentTriggerTime(String cron) {
        List<String> list = new ArrayList<String>();
        try {
            CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
            cronTriggerImpl.setCronExpression(cron);
            // 这个是重点，一行代码搞定
            List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 8);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (Date date : dates) {
                list.add(dateFormat.format(date));
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 添加job到调度器
     * @param job
     * @throws SchedulerException
     */
    public static void addJob(SystemJob job) throws SchedulerException, ClassNotFoundException {

        if (scheduler == null) {
            StdSchedulerFactory factory = new StdSchedulerFactory(CONFIG_NAME);
            scheduler = factory.getScheduler();
        }
        JobDetail jobDetail = addJobDetail(job);
        CronTrigger cronTrigger = addCronTrigger(job.getTriggerName(),job.getCronExpression());

        // 注册新的定时任务到调度器
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }

    /**
     * 添加基于cron表达式的触发器
     * @param triggerName
     * @param cronExpression
     * @return
     * @throws SchedulerException
     */
    public static CronTrigger addCronTrigger(String triggerName, String cronExpression) throws SchedulerException {

        CronTrigger cronTrigger = getCronTrigger(triggerName);
        // 如果调度器中不存在该任务名所对应的触发器，则创建一个新的触发器
        if (cronTrigger == null) {
            cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerName,GROUP_NAME).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();
            logger.debug("成功添加名称为{}的触发器到调度器,对应CRON表达式为", triggerName, cronExpression);
        } else {
            logger.debug("调度器中已经存在名称为{}的触发器，这里不再进行处理", triggerName);
        }

        return  cronTrigger;
    }

    /**
     * 从调度器中获取触发器
     * @param triggerName
     * @return
     * @throws SchedulerException
     */
    public static CronTrigger getCronTrigger(String triggerName) throws SchedulerException {
        return (CronTrigger)scheduler.getTrigger(TriggerKey.triggerKey(triggerName,GROUP_NAME));
    }

    /**
     * 获取jobDetail
     * @param job
     * @return
     * @throws SchedulerException
     * @throws ClassNotFoundException
     */
    public static JobDetail addJobDetail(SystemJob job) throws SchedulerException, ClassNotFoundException {

        JobDetail jobDetail = getJobDetail(job.getJobName());
        // 如果调度器中不存在该jobName对应的job,则创建一个jobDteil;
        if (jobDetail == null) {
            Class<? extends org.quartz.Job> jobClass = (Class<? extends org.quartz.Job>) Class.forName(job.getJobImplClass());
            jobDetail = JobBuilder.newJob(jobClass).build();
            logger.info("job[" + job.getJobName() + "]" + "成功加入到调度器,对应处理类为[" + job.getJobImplClass() + "]\n");
        } else {
            logger.debug("调度器中已经存在名称为：{}的任务，这里不做处理", job.getJobName());
        }

        return jobDetail;
    }

    /**
     * 从调度器中获取job属性
     * @param jobName
     * @return
     * @throws SchedulerException
     */
    public static JobDetail getJobDetail(String jobName) throws SchedulerException {
        return scheduler.getJobDetail(JobKey.jobKey(jobName,GROUP_NAME));
    }




}
